package cn.com.wangluotongxin.netty.rabbitmq;

import cn.com.wangluotongxin.chat.netty.ChatNettyQueue;
import cn.com.wangluotongxin.chat.netty.pojo.*;
import cn.com.wangluotongxin.netty.cache.NettyChannelCacheUtil;
import cn.com.wangluotongxin.netty.constants.MsgType;
import cn.com.wangluotongxin.netty.constants.RedisCacheKey;
import cn.com.wangluotongxin.netty.pojo.ChannelPojo;
import cn.com.wangluotongxin.rabitmq.service.RabbitMqService;
import cn.com.wangluotongxin.redis.service.RedisService;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import io.netty.channel.Channel;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

@Slf4j
@Component
public class RabbitmqListener {

    @Autowired
    private RedisService redisService;

    @Autowired
    private RabbitMqService rabbitMqService;

    /**
     * 登录响应
     */
    @RabbitListener(queues = ChatNettyQueue.CHAT_LOGIN_RESPONSE, ackMode = "AUTO")
    public void loginResponse(LoginResponseInfo info){
        if(StrUtil.isBlank(info.getChannelId())) return;
        if(!redisService.setNx(RedisCacheKey.CACHE_KEY.concat("LOGIN:RESPONSE:").concat(info.getChannelId()), info.getChannelId(), 3)){
            log.info("登录重复响应:{}", info.getChannelId());
            return;
        }

        ChannelPojo channelPojo = NettyChannelCacheUtil.get(info.getChannelId());
        if(channelPojo == null) return;
        Channel channel = channelPojo.getChannel();
        Map<String, Object> responseMap = new HashMap<>();
        responseMap.put("msgType", MsgType.LOGIN_RESPONSE);
        responseMap.put("result", "success");
        responseMap.put("date", DateUtil.date());
        channel.writeAndFlush(new TextWebSocketFrame(JSONObject.toJSONString(responseMap)));
    }

    /**
     *  发送消息
     */
    @RabbitListener(queues = ChatNettyQueue.CHAT_SEND_MESSAGE, ackMode = "AUTO")
    public void sendMessage(SendChatMessage message){
        if(message.getMessageId() == null) return;
        if(!redisService.setNx(RedisCacheKey.CACHE_KEY.concat("SEND:MESSAGE:").concat(message.getMessageId().toString()), message.getMessageId(), 60)){
            log.info("重复发送信息:client-channel-id:{}, message-id: {}", message.getChannelId(), message.getMessageId());
            return;
        }

        for(String channelId : message.getAcceptChannelIds()){
            if(StrUtil.isBlank(channelId)) continue;
            ChannelPojo channelPojo = NettyChannelCacheUtil.get(channelId);
            if(channelPojo == null) continue;

            Channel channel = channelPojo.getChannel();
            Map<String, Object> messageMap = new HashMap<>();
            messageMap.put("msgType", MsgType.SEND_MESSAGE);
            messageMap.put("messageId", message.getMessageId());
            channel.writeAndFlush(new TextWebSocketFrame(JSONObject.toJSONString(messageMap)));
        }

        Map<String, Object> responseMap = new HashMap<>();
        responseMap.put("msgType", MsgType.SEND_MESSAGE_RESPONSE);
        responseMap.put("result", "success");
        responseMap.put("channelId", message.getChannelId());
        responseMap.put("messageId", message.getMessageId());
        responseMap.put("date", DateUtil.date());
        rabbitMqService.sendMessage(ChatNettyQueue.CHAT_SEND_MESSAGE_RESPONSE, responseMap);
    }

    /**
     * 阅读消息
     */
    @RabbitListener(queues = ChatNettyQueue.CHAT_MESSAGE_HAVE_READ, ackMode = "AUTO")
    public void chatMessageRefresh(ChatMessageHaveRead read){
        ChannelPojo channelPojo = NettyChannelCacheUtil.get(read.getChannelId());
        if(channelPojo == null) return;
        Channel channel = channelPojo.getChannel();

        Map<String, Object> messageMap = new HashMap<>();
        messageMap.put("msgType", MsgType.CHAT_MESSAGE_HAVE_READ);
        messageMap.put("messageIds", read.getMessageIds());
        channel.writeAndFlush(new TextWebSocketFrame(JSONObject.toJSONString(messageMap)));
    }

    /**
     * 事件上报
     */
    @RabbitListener(queues = ChatNettyQueue.CHAT_EVENT_PUSH, ackMode = "AUTO")
    public void eventPush(EventPushInfo info){
        log.info("收到事件上报:{}", JSONObject.toJSONString(info));
        ChannelPojo channelPojo = NettyChannelCacheUtil.get(info.getChannelId());
        if(channelPojo == null) return;
        Channel channel = channelPojo.getChannel();

        Map<String, Object> messageMap = new HashMap<>();
        messageMap.put("msgType", MsgType.CHAT_EVENT_PUSH);
        messageMap.put("data", info.getData());
        channel.writeAndFlush(new TextWebSocketFrame(JSONObject.toJSONString(messageMap)));
    }

    /**
     * 系统消息发送
     */
    @RabbitListener(queues = ChatNettyQueue.CHAT_SYS_MESSAGE_SEND, ackMode = "AUTO")
    public void sysMessage(SysMessageSend message){
        log.info("收到系统消息发送上报:{}", JSONObject.toJSONString(message));
        ChannelPojo channelPojo = NettyChannelCacheUtil.get(message.getChannelId());
        if(channelPojo == null) return;
        Channel channel = channelPojo.getChannel();

        Map<String, Object> messageMap = new HashMap<>();
        messageMap.put("msgType", MsgType.CHAT_SYS_MESSAGE_SEND);
        messageMap.put("data", message.getData());
        channel.writeAndFlush(new TextWebSocketFrame(JSONObject.toJSONString(messageMap)));
    }
}
